#include <pspkernel.h>
#include <pspsdk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pspctrl.h>
#include "kerror.h"
#include "splash.h"
#include <time.h>
#include "..\states.h"


PSP_MODULE_INFO("PSP3JB", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

SceCtrlData pad;
int timeout = 0;
clock_t now = 0;
clock_t endtime = 0;

#include "..\usbdriver\defines.h"

#include "gui.c"
#include "procs.c"

char logbuffer[1024 * 10];  // 10 KB buffer...
long logsize = 0;			//Actual size...

void loginit() { int fp = sceIoOpen("ms0:/psp3jb_log.txt", PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC , 0777 ); sceIoClose(fp); }
void logecho(char *msg) { 
	strcat(logbuffer,msg);
	logsize += strlen(msg);
	if ( logsize >= 2*1024 ) {
		int fp = sceIoOpen("ms0:/psp3jb_log.txt", PSP_O_WRONLY | PSP_O_APPEND , 0777 ); sceIoWrite(fp, logbuffer, logsize); sceIoClose(fp);
		memset(&logbuffer,0,1024*10);
		logsize = 0;
	}
}

void logsave() { int fp = sceIoOpen("ms0:/psp3jb_log.txt", PSP_O_WRONLY | PSP_O_APPEND , 0777 ); sceIoWrite(fp, logbuffer, logsize); sceIoClose(fp); }

/* comm */
int register_udriver();
int start_mainusbbus();
int start_mainusbdrv();
int activate_usbdriv();
int drivers_stop_all();
void stepperfunction(struct passingdata *ptr);

int running = 1;

/* Callbacks */
int exit_callback(int arg1, int arg2, void *common) { logsave(); running = 0; drivers_stop_all(); sceKernelExitGame(); return 0; }
static int CallbackThread(SceSize args, void *argp) {
   int cbid; 
   cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
   sceKernelRegisterExitCallback(cbid);
   sceKernelSleepThreadCB();
   return 0;
}
static int SetupCallbacks(void) {
   int thid = 0;
   thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
   if(thid >= 0) { sceKernelStartThread(thid, 0, 0); }
   return thid;
}

static clock_t getCurrentMilliseconds() {
	return (clock() / (clock_t)(CLOCKS_PER_SEC *0.001));
}

int main(int argc, char *argv[]) {
	SetupCallbacks();
	screeninit();
	loginit();
	sceCtrlSetSamplingCycle(0);
	sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL);
	
	#ifndef SPLASH0
		// regex from:	<span style="color:#([0-9A-F][0-9A-F])([0-9A-F][0-9A-F])([0-9A-F][0-9A-F])">([A-Z])</span>
		// to: 			fcolor(0xFF\3\2\1); printf("\3");
		SPLASH0
		zzz(100);
	#endif
	
	/* START HUB DRIVER */ guidraw(); zzz(20); driverint("usbdriver.prx"); zzz(20);
	
	while (1) {
		resetdata(&res);
		res.status = estado;
		if ( endtime > 0 ) {
			if ( now > endtime ) { res.timeout = 0; }
			else { res.timeout = 1; }
		}
		
		
		stepperfunction(&res);
		estado = res.status;
		int i;
		for (i=0;i<6;i++) { 
			localports[i].status = res.ports[i].status;
			localports[i].change = res.ports[i].change;
		}
		guidraw();
		
		switch (estado) {
			case APP_INIT:
				if ( register_udriver() == 0 ) { localhubstatus.regged = 1; guidraw(); zzz(20); }
				if ( start_mainusbbus() == 0 ) { localhubstatus.started = 2; guidraw(); zzz(20); }
				if ( start_mainusbdrv() == 0 ) { localhubstatus.started = 2; guidraw(); zzz(20); }
				if ( activate_usbdriv() == 0 ) { localhubstatus.started = 1; guidraw(); zzz(20); }
				driverint("kdumper.prx");
				break;
			case APP_READY:
				pl(res.text);
				logecho(res.text);
				break;
			case APP_HUB_READY:
				now = getCurrentMilliseconds();
				if ( res.timeout > 0 ) { /* GOT TIMEOUT */
					timeout = res.timeout;
					fcolor(ABGR(155,155,155,255)); 	pl("[T] ");  fcolor(ABGR(255,255,255,255));  pf("Temporizador: %i ms\n",timeout);
					endtime = now + timeout;
				}
				if ( endtime > 0 && now > endtime ) { 
					endtime = 0; fcolor(ABGR(155,155,155,255)); 	pl("[T] "); fcolor(ABGR(0,255,0,255));  pl("RIIING\n"); fcolor(ABGR(255,255,255,255));
				}
				pl(res.text);
				logecho(res.text);
				break;
				
			case APP_DEV1_WAIT:
				pl(res.text);
				logecho(res.text);
				break;
			
			case APP_TERM:
				appkilled();
				break;
				
			default:
				break;
		}
		
		if ( running == 0 ) { sceKernelExitGame(); }
	}
	
	return 0;
}
